#include "appManager.h"

#include <gl/gl.h>
#include <gl/glu.h>

#include "glWindow.h"
#include "glText.h"

appManager::appManager():
m_input( Input(&m_camera) ),
m_frameTime(0.0f),
m_frameCounter(1)
{
	m_glWindow =  new glWindow;
	m_glText   =  new glText(S_WIDTH,S_HEIGHT);
}

void appManager::init(HWND hwnd)
{
	m_glWindow->Init(hwnd);
	//ShowWin32Console();
	m_glText->buildFont(m_glWindow->getHdc());	// Build The Font

	m_quadratic=gluNewQuadric();				// Create A Pointer To The Quadric Object
	gluQuadricNormals(m_quadratic, GL_SMOOTH);	// Create Smooth Normals
	gluQuadricTexture(m_quadratic, GL_TRUE);	// Create Texture Coords
}

void appManager::update(int frameRate, HWND hwnd)
{
	m_frameTimer.startTimer();

	m_input.mouseMove(hwnd);
	m_input.keyboard();

	updateCamera();

	render();

	m_frameTimer.stopTimer();
	m_frameTime = m_frameTimer.getElapsedTime();
	m_frameCounter++;
}

void appManager::release()
{
	m_glText->killFont();
	m_input.release();

	delete m_glWindow;
	delete m_glText;

	m_glWindow = NULL;
	m_glText   = NULL;
}

void appManager::updateCamera()
{
	// load Identity Matrix
	glLoadIdentity();

	const JPVec3 &lookat	= m_camera.lookat();
	const JPVec3 &position	= m_camera.position();
	const JPVec3 &up		= m_camera.up();

	gluLookAt(position.x,  position.y,  position.z,	
		lookat.x, lookat.y, lookat.z,	
		up.x,   up.y,  up.z);
}

void appManager::render() 
{
	// Clear The Screen And The Depth Buffer	
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//Draw plane
	glEnable(GL_LIGHTING);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	glBegin(GL_QUADS);
	glNormal3f(0.0f,1.0f,0.0f);
	glVertex3f(-400.0f,0.0f,-400.0f);
	glNormal3f(0.0f,1.0f,0.0f);
	glVertex3f(400.0f,0.0f,-400.0f);
	glNormal3f(0.0f,1.0f,0.0f);
	glVertex3f(400.0f,0.0f,400.0f);
	glNormal3f(0.0f,1.0f,0.0f);
	glVertex3f(-400.0f,0.0f,400.0f);
	glEnd();

	glDisable(GL_LIGHTING);

	glColor3f(1.0f,1.0f,0.0f);
	m_glText->print(0, 0, "Number of objects %d ", NOOBJECT );
	m_glText->print(700, 584, "FPS %.2f", 1.0f/m_frameTime);
	m_glText->print(0, 16, "Time to calculate frame:   %f", m_frameTime);

	// Swap the frame buffers.
	SwapBuffers(m_glWindow->getHdc());
}

bool appManager::animateNextFrame(int desiredFrameRate)
{
	static float lastTime = (float)GetTickCount() * 0.001f;
	static float elapsedTime = 0.0f;

	float currentTime	= (float)GetTickCount() * 0.001f;	// Get the time (milliseconds = seconds * .001)
	float deltaTime		= currentTime - lastTime;			// Get the slice of time
	float desiredFPS	= 1.0f /(float)desiredFrameRate;	// Store 1 / desiredFrameRate

	lastTime = currentTime;		// Update lastTime  
	elapsedTime += deltaTime;	// Add to the elapsed time	

	// Check if the time since we last checked is greater than our desiredFPS
	if( elapsedTime > desiredFPS )
	{
		elapsedTime -= desiredFPS;	// Adjust our elapsed time		
		return true;// Return true, to animate the next frame of animation
	}

	// We don't animate right now.
	return false;
}